package com.fang.dubbo.mock.rpc.netty;

import com.fang.dubbo.mock.rpc.protocol.Invocation;
import com.fang.dubbo.mock.rpc.register.RemoteMapRegister;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * @author fanglingxiao
 * @version 1.0
 * @description TODO
 * @date 2022/1/2 12:34 下午
 **/
@Slf4j
public class NettyServerHandler extends ChannelHandlerAdapter {
    /**
     * 获取客服端发送的消息,并调用服务
     *
     * @param ctx ctx
     * @param msg 请求参数
     * @throws Exception e
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("provider channelRead 被调用");
        log.info("msg -> {}", msg);
        Invocation invocation = (Invocation) msg;
        if (!RemoteMapRegister.containsKey(invocation.getInterfaceName())) {
            log.error("no rpc provider");
        }
        // 反射调用
        Class<?> clazz = RemoteMapRegister.getImpl(invocation.getInterfaceName());
        Method method = clazz.getMethod(invocation.getMethodName(), invocation.getParamTypes());
        Object response = null;
        try {
            response = method.invoke(clazz.newInstance(), invocation.getParams());
            log.info("invoke response = {}", response);
        } catch (Exception e) {
            log.error("NettyServerHandler invoke method error", e);
        }
        ctx.writeAndFlush(response);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
